/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2009 - 2012 Luca Mingardi.
 *
 * This file is part of jeeObserver.
 *
 * JeeObserver is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * JeeObserver is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
package jeeobserver;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import jeeobserver.server.JeeObserverClient;
import jeeobserver.server.JeeObserverServerContext;
import jeeobserver.server.JeeObserverServerException;
import jeeobserver.server.settings.ActionExclusionRule;
import jeeobserver.server.settings.ActionNotificationRule;
import jeeobserver.server.settings.Condition;
import jeeobserver.server.settings.Condition.BooleanCondition;
import jeeobserver.server.settings.Condition.NumberCondition;
import jeeobserver.server.settings.Condition.TextCondition;
import jeeobserver.server.settings.Condition.TimePeriodCondition;
import jeeobserver.server.settings.HardDiskExclusionRule;
import jeeobserver.server.settings.LoggerNotification;
import jeeobserver.server.settings.Settings;
import jeeobserver.server.settings.TimePeriod;
import jeeobserver.utilities.SizeUtilities;
import jeeobserver.utilities.TimeUtilities;

class LoadTest {

    private static final int SERVER_PORT = 5688;

    private static final String SERVER_HOST = "localhost";

    private static final long ACTION_INVOCATIONS_NUMBER = 10000;

    private static final long HTTP_SESSION_INVOCATIONS_NUMBER = 10000;

    private static final long JVM_INVOCATIONS_NUMBER = 10000;

    private static final long HD_INVOCATIONS_NUMBER = 10000;

    private static final long EXCEPTION_FREQUECY = 1000;
    //private static final String[] PRINCIPAL_SET = new String[]{null, "albino.luciani", "antonio.montini", "giuseppe.roncalli", "giovanni.pacelli", "ambrogio.ratti", "giacomo.chiesa", "melchiorre.sarto"};

    private static final String[] PRINCIPAL_SET = new String[]{null, "albino.luciani", "antonio.montini", "giuseppe.roncalli", "giovanni.pacelli", "ambrogio.ratti", "giacomo.chiesa", "melchiorre.sarto"};
    //private static final String[] PRINCIPAL_SET = new String[]{"albino.luciani"};

    private static final String[] PROJECT_SET = new String[]{"jeeObserver GUI", "jeeObserver Server", "jeeObserver WS"};
    //private static final String[] PROJECT_SET = new String[]{"jeeObserver GUI"};

    private static final String[] PATH_SET = new String[]{"TEST 1", "TEST 2", "TEST 3"};

    private static final String context = "192.168.0.1";

    private static final boolean EJB_ENABLED = true;

    private static final boolean JSF_ENABLED = true;

    private static final boolean SERVLET_ENABLED = true;

    private static final boolean JVM_ENABLED = true;

    private static final boolean HARD_DISK_ENABLED = true;

    private static final boolean HTTP_SESSION_ENABLED = true;

    private static final Random RANDOM_GENERATOR = new Random();

    private static final int TIME_UNIT = Calendar.MINUTE;

    private static final int TIME_RANGE = 1;

    public static void main(String[] args) throws JeeObserverServerException {

        // Create jeeObserver context instance
        JeeObserverContext.createInstance(LoadTest.context, LoadTest.SERVER_HOST, LoadTest.SERVER_PORT, 5000000, 5000);
        JeeObserverContext.logger.setLevel(Level.ALL);

        // Create client
        final JeeObserverClient client = new JeeObserverClient(LoadTest.SERVER_HOST, LoadTest.SERVER_PORT);

        // Create settings
        final Settings settings = new Settings();

        // Createaction exclusion rule 1
        final ActionExclusionRule actionExclusionRule1 = new ActionExclusionRule();

        actionExclusionRule1.setName("Action exclusion rule 1");

        actionExclusionRule1.setCategoryCondition(new NumberCondition(Condition.OPERATOR_NUMBER_EQUAL, ActionObserver.CATEGORY_EJB));
        actionExclusionRule1.setElementNameCondition(new TextCondition(Condition.OPERATOR_TEXT_EQUAL, "com.jeeobserver.ejb.package.SessionBeanToExclude"));
        settings.getActionExclusionRulesList().add(actionExclusionRule1);

        // Createaction exclusion rule 2
        final ActionExclusionRule actionExclusionRule2 = new ActionExclusionRule();
        actionExclusionRule2.setName("Action exclusion rule 2");

        actionExclusionRule2.setCategoryCondition(new NumberCondition(Condition.OPERATOR_TEXT_EQUAL, ActionObserver.CATEGORY_JSF));
        actionExclusionRule2.setElementNameCondition(new TextCondition(Condition.OPERATOR_TEXT_CONTAINS, "ActionToExclude"));

        settings.getActionExclusionRulesList().add(actionExclusionRule2);

        // Createaction exclusion rule 3
        final ActionExclusionRule actionExclusionRule3 = new ActionExclusionRule();
        actionExclusionRule3.setName("Action exclusion rule 3");

        actionExclusionRule3.setCategoryCondition(new NumberCondition(Condition.OPERATOR_TEXT_EQUAL, ActionObserver.CATEGORY_SERVLET));
        actionExclusionRule3.setElementNameCondition(new TextCondition(Condition.OPERATOR_TEXT_BEGIN_WITH, "/jeeobserver/servlet/ServletToExclude"));

        settings.getActionExclusionRulesList().add(actionExclusionRule3);

        // Createaction exclusion rule 4
        final ActionExclusionRule actionExclusionRule4 = new ActionExclusionRule();
        actionExclusionRule4.setName("Action exclusion rule 4");

        actionExclusionRule4.setDurationCondition(new TimePeriodCondition(Condition.OPERATOR_NUMBER_GREATER_THAN, new TimePeriod(TimePeriod.UNIT_MILLISECOND, 10)));
        actionExclusionRule4.setActive(false);

        settings.getActionExclusionRulesList().add(actionExclusionRule4);

        // Createaction notification rule 1
        final LoggerNotification notification = new LoggerNotification("Subject", "Testo:\ncontext:{context}\ncategory:{category}\nproject:{project}\nname:{name}\nstart_timestamp:{start_timestamp}\ncpu_nanos:{cpu_nanos}\ntime_nanos:{time_nanos}\nexception_message:{exception_message}\nexception_stack_trace:{exception_stack_trace}");

        final ActionNotificationRule actionNotificationRule1 = new ActionNotificationRule(notification);
        actionNotificationRule1.setName("Action notification rule 1");

        actionNotificationRule1.setContextCondition(new TextCondition(Condition.OPERATOR_TEXT_EQUAL, "CONTEXT_NOT_EXISTS"));
        actionNotificationRule1.setExceptionThrowedCondition(new BooleanCondition(Condition.OPERATOR_BOOLEAN_EQUAL, true));

        actionNotificationRule1.setActive(true);

        settings.getActionNotificationRulesList().add(actionNotificationRule1);


        //Create hard disk exclusion rule

        settings.setHardDiskExclusionRulesList(new ArrayList<HardDiskExclusionRule>());

        HardDiskExclusionRule exclusionRule = new HardDiskExclusionRule();
        exclusionRule.setPathCondition(new TextCondition(TextCondition.OPERATOR_TEXT_NOT_CONTAINS, "TEST"));
        exclusionRule.setActive(true);
        exclusionRule.setName("Hard Disk exclusion rule 1");

        //settings.getHardDiskExclusionRulesList().add(exclusionRule);

        // Update settings
        client.updateSettings(settings);


        //Starting date

        //Calendar calendar = new GregorianCalendar(2_013, 1, 1, 0, 1, 0);
        Calendar calendar = new GregorianCalendar();
        //calendar.setTime(new Date());

        // EJB Test
        if (LoadTest.EJB_ENABLED) {
            JeeObserverServerContext.logger.log(Level.INFO, "Inserting EJB fake elements.");

            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_EJB, "com.jeeobserver.ejb.package.SessionBeanToExclude", LoadTest.ACTION_INVOCATIONS_NUMBER, 0, 5, 5, 10);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_EJB, "com.jeeobserver.ejb.package.SessionBeanToShow", LoadTest.ACTION_INVOCATIONS_NUMBER, 0, 5, 5, 10);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_EJB, "com.jeeobserver.ejb.package.SessionBeanToNotificate", 3, 0, 100, 1000, 1200);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_EJB, "com.jeeobserver.ejb.package.SessionBeanDummy", LoadTest.ACTION_INVOCATIONS_NUMBER, 10, 15, 50, 70);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_EJB, "com.jeeobserver.ejb.package.SessionBeanDummyHighTime", LoadTest.ACTION_INVOCATIONS_NUMBER, 0, 5, 200, 500);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_EJB, "com.jeeobserver.ejb.package.SessionBeanDummyHighCpu", LoadTest.ACTION_INVOCATIONS_NUMBER, 200, 300, 210, 310);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_EJB, "com.jeeobserver.ejb.package.SessionBeanDummyLowTime", LoadTest.ACTION_INVOCATIONS_NUMBER, 0, 10, 10, 50);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_EJB, "com.jeeobserver.ejb.package.SessionBeanDummyLowCpu", LoadTest.ACTION_INVOCATIONS_NUMBER, 10, 20, 15, 25);
        }

        // JSF Test
        if (LoadTest.JSF_ENABLED) {
            JeeObserverServerContext.logger.log(Level.INFO, "Inserting JSF fake elements.");

            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_JSF, "com.jeeobserver.jsf.package.ActionToExclude", LoadTest.ACTION_INVOCATIONS_NUMBER, 10, 20, 50, 70);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_JSF, "com.jeeobserver.jsf.package.ActionToShow", LoadTest.ACTION_INVOCATIONS_NUMBER, 10, 20, 50, 70);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_JSF, "com.jeeobserver.jsf.package.ActionToNotificate", 3, 10, 50, 50, 70);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_JSF, "com.jeeobserver.jsf.package.ActionDummy", LoadTest.ACTION_INVOCATIONS_NUMBER, 10, 20, 50, 70);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_JSF, "com.jeeobserver.jsf.package.ActionDummyHighTime", LoadTest.ACTION_INVOCATIONS_NUMBER, 0, 5, 200, 300);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_JSF, "com.jeeobserver.jsf.package.ActionDummyHighCpu", LoadTest.ACTION_INVOCATIONS_NUMBER, 200, 300, 210, 310);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_JSF, "com.jeeobserver.jsf.package.ActionDummyLowTime", LoadTest.ACTION_INVOCATIONS_NUMBER, 0, 5, 10, 20);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_JSF, "com.jeeobserver.jsf.package.ActionDummyLowCpu", LoadTest.ACTION_INVOCATIONS_NUMBER, 10, 50, 15, 25);
        }

        // Servlet Test
        if (LoadTest.SERVLET_ENABLED) {
            JeeObserverServerContext.logger.log(Level.INFO, "Inserting Servlet fake elements.");

            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_SERVLET, "/jeeobserver/servlet/ServletToExclude.jsp", LoadTest.ACTION_INVOCATIONS_NUMBER, 10, 20, 50, 100);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_SERVLET, "/jeeobserver/servlet/ServletToShow.jsp", LoadTest.ACTION_INVOCATIONS_NUMBER, 10, 20, 50, 100);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_SERVLET, "/jeeobserver/servlet/ServletToNotificate.jsp", 3, 10, 20, 50, 200);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_SERVLET, "/jeeobserver/servlet/ServletDummy.jsp", LoadTest.ACTION_INVOCATIONS_NUMBER, 10, 20, 50, 70);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_SERVLET, "/jeeobserver/servlet/ServletDummyHighTime.jsp", LoadTest.ACTION_INVOCATIONS_NUMBER, 0, 20, 200, 300);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_SERVLET, "/jeeobserver/servlet/ServletDummyHighCpu.jsp", LoadTest.ACTION_INVOCATIONS_NUMBER, 200, 300, 210, 310);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_SERVLET, "/jeeobserver/servlet/ServletDummyLowTime.jsp", LoadTest.ACTION_INVOCATIONS_NUMBER, 0, 10, 10, 20);
            LoadTest.createFakeActionCoreElementSet(calendar.getTime(), ActionObserver.CATEGORY_SERVLET, "/jeeobserver/servlet/ServletDummyLowCpu.jsp", LoadTest.ACTION_INVOCATIONS_NUMBER, 10, 50, 15, 25);
        }

        // JVM Test
        if (LoadTest.JVM_ENABLED) {
            JeeObserverServerContext.logger.log(Level.INFO, "Inserting JVM fake elements.");
            LoadTest.createFakeJvmCoreElementSet(calendar.getTime(), LoadTest.JVM_INVOCATIONS_NUMBER, TimeUtilities.SECOND_NANOS * 5, TimeUtilities.MILLIS_NANOS * 5000, 2, 20, SizeUtilities.MB_BYTES * 75, SizeUtilities.MB_BYTES * 90, SizeUtilities.MB_BYTES * 128, SizeUtilities.MB_BYTES * 35, SizeUtilities.MB_BYTES * 38, SizeUtilities.MB_BYTES * 64);
        }

        // Http Session Test
        if (LoadTest.HTTP_SESSION_ENABLED) {
            JeeObserverServerContext.logger.log(Level.INFO, "Inserting HTTP Session fake elements.");
            LoadTest.createFakeHttSessionElementSet(calendar.getTime(), LoadTest.HTTP_SESSION_INVOCATIONS_NUMBER, TimeUtilities.HOUR_NANOS, "ABCDEFGHILM_");
        }

        // Hard disk Test
        if (LoadTest.HARD_DISK_ENABLED) {
            JeeObserverServerContext.logger.log(Level.INFO, "Inserting Hard Disk fake elements.");
            LoadTest.createFakeHardDiskElementSet(calendar.getTime(), LoadTest.HD_INVOCATIONS_NUMBER, SizeUtilities.MB_BYTES * 5000, SizeUtilities.MB_BYTES * 50, SizeUtilities.MB_BYTES * 50);
        }

        // Close jeeObserver context
        JeeObserverContext.getInstance().close();
        JeeObserverServerContext.logger.log(Level.INFO, "jeeObserver context closed.");
    }

    private static void createFakeActionCoreElementSet(Date date, int category, String name, long quantity, long minCpu, long maxCpu, long minTime, long maxTime) {

        final Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        for (long i = 0; i < quantity; i++) {

            calendar.add(LoadTest.TIME_UNIT, LoadTest.getRandomRange(1, LoadTest.TIME_RANGE));

            final long cpuNanos = LoadTest.getRandomRange(minCpu * 1000000, maxCpu * 1000000);
            final long timeNanos = LoadTest.getRandomRange(minTime * 1000000, maxTime * 1000000);

            Exception actionException = null;

            try {
                final long exNum = 1 / LoadTest.getRandomRange(0, LoadTest.EXCEPTION_FREQUECY);

                if (exNum > LoadTest.EXCEPTION_FREQUECY) {
                    JeeObserverServerContext.logger.log(Level.INFO, "Not possible.");
                }

            } catch (final Exception e) {
                actionException = e;
            }

            ActionObserver.Exception actionObserverException = null;
            if (actionException != null) {
                actionObserverException = new ActionObserver.Exception(actionException);
            }

            final ActionObserver element = new ActionObserver(calendar.getTime(), LoadTest.context, LoadTest.getRandomProject(), category, name, timeNanos, cpuNanos, LoadTest.getRandomPrincipal(), actionObserverException);

            JeeObserverContext.getInstance().addObserver(element);

            delay();
        }

        JeeObserverServerContext.logger.log(Level.INFO, "Created {0} elements named: {1}.", new Object[]{String.valueOf(quantity), name});
    }

    private static void createFakeJvmCoreElementSet(Date date, long quantity, long timeNanosCount, long cpuNanosCount, int processorsCount, int threadsCount, long heapUsedBytes, long heapCommittedBytes, long heapMaxBytes, long nonHeapUsedBytes, long nonHeapCommittedBytes, long nonHeapMaxBytes) {

        final Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);


        for (long i = 0; i < quantity; i++) {

            calendar.add(LoadTest.TIME_UNIT, LoadTest.getRandomRange(1, LoadTest.TIME_RANGE));

            //final CoreElement element = new JvmCoreElement(LoadTest.context, calendar.getTime(), LoadTest.getRandomRange(timeNanosCount, timeNanosCount + TimeUtilities.MILLIS_NANOS * 3), LoadTest.getRandomRange(cpuNanosCount, cpuNanosCount + TimeUtilities.MILLIS_NANOS * 300), processorsCount, LoadTest.getRandomRange(threadsCount, threadsCount + 10), LoadTest.getRandomRange(heapUsedBytes, heapUsedBytes + (SizeUtilities.MB_BYTES * 20)), LoadTest.getRandomRange(heapCommittedBytes, heapCommittedBytes + (SizeUtilities.MB_BYTES * 20)), heapMaxBytes, LoadTest.getRandomRange(nonHeapUsedBytes, nonHeapUsedBytes + (SizeUtilities.MB_BYTES * 20)), LoadTest.getRandomRange(nonHeapCommittedBytes, nonHeapCommittedBytes + (SizeUtilities.MB_BYTES * 20)), nonHeapMaxBytes);
            final JvmObserver element = new JvmObserver(calendar.getTime(),
                    LoadTest.context,
                    timeNanosCount,
                    (cpuNanosCount + (LoadTest.getRandomRange(0, TimeUtilities.SECOND_NANOS) * 10)),
                    processorsCount,
                    LoadTest.getRandomRange(threadsCount, threadsCount + 10),
                    LoadTest.getRandomRange(heapUsedBytes,
                    heapUsedBytes + (SizeUtilities.MB_BYTES * 20)),
                    LoadTest.getRandomRange(heapCommittedBytes,
                    heapCommittedBytes + (SizeUtilities.MB_BYTES * 20)),
                    heapMaxBytes,
                    LoadTest.getRandomRange(nonHeapUsedBytes, nonHeapUsedBytes + (SizeUtilities.MB_BYTES * 20)),
                    LoadTest.getRandomRange(nonHeapCommittedBytes, nonHeapCommittedBytes + (SizeUtilities.MB_BYTES * 20)),
                    nonHeapMaxBytes);

            JeeObserverContext.getInstance().addObserver(element);

            delay();
        }

        JeeObserverServerContext.logger.log(Level.INFO, "Created {0} elements.", new Object[]{String.valueOf(quantity)});
    }

    private static void createFakeHttSessionElementSet(Date date, long quantity, long timeNanosCount, String sessionId) {

        final Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);

        for (long i = 0; i < quantity; i++) {

            //calendar.add(LoadTest.TIME_UNIT, LoadTest.getRandomRange(1, LoadTest.TIME_RANGE));
            //calendar.add(LoadTest.TIME_UNIT, new Long(1 + i).intValue());
            calendar.add(LoadTest.TIME_UNIT, 1);

            final String project = LoadTest.getRandomProject();

            final HttpSessionObserver elementStart = new HttpSessionObserver(calendar.getTime(), LoadTest.context, project, -1);
            JeeObserverContext.getInstance().addObserver(elementStart);

            if (getRandomRange(0, 10) > 3) {
                //final CoreElement elementEnd = new HttpSessionCoreElement(LoadTest.context, project, calendar.getTime(), (TimeUtilities.MINUTE_NANOS * LoadTest.getRandomRange(0, 240)));
                final HttpSessionObserver elementEnd = new HttpSessionObserver(calendar.getTime(), LoadTest.context, project, (TimeUtilities.MINUTE_NANOS * 60));
                JeeObserverContext.getInstance().addObserver(elementEnd);
            }

            delay();
        }

        JeeObserverServerContext.logger.log(Level.INFO, "Created {0} elements.", new Object[]{String.valueOf(quantity)});
    }

    private static void createFakeHardDiskElementSet(Date date, long quantity, long maxTotalBytes, long maxUsableBytes, long maxFreeBytes) {

        final Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);

        for (long i = 0; i < quantity; i++) {

            calendar.add(LoadTest.TIME_UNIT, 1);

            final long totalBytes = LoadTest.getRandomRange(maxTotalBytes - (SizeUtilities.MB_BYTES * 5), maxTotalBytes + (SizeUtilities.MB_BYTES * 5));
            final long usableBytes = LoadTest.getRandomRange(maxUsableBytes - (SizeUtilities.MB_BYTES * 50), maxUsableBytes + (SizeUtilities.MB_BYTES * 50));
            final long freeBytes = LoadTest.getRandomRange((maxFreeBytes + (SizeUtilities.KB_BYTES * (i * 10))) - (SizeUtilities.MB_BYTES * 50), maxFreeBytes + (SizeUtilities.MB_BYTES * 50));
            //final long usableBytes = maxUsableBytes - (SizeUtilities.KB_BYTES * (i));
            //final long freeBytes = maxFreeBytes - (SizeUtilities.MB_BYTES * 50) + (SizeUtilities.KB_BYTES * (i));

            final String path = LoadTest.getRandomPath();

            final HardDiskObserver element = new HardDiskObserver(calendar.getTime(), LoadTest.context, path, totalBytes, usableBytes, freeBytes, totalBytes - freeBytes);
            JeeObserverContext.getInstance().addObserver(element);

            delay();
        }

        JeeObserverServerContext.logger.log(Level.INFO, "Created {0} elements.", new Object[]{String.valueOf(quantity)});
    }

    private static int getRandomRange(long minValue, long maxValue) {

        return new Long(LoadTest.getRandomRange(new Long(minValue).intValue(), new Long(maxValue).intValue())).intValue();
    }

    private static int getRandomRange(int minValue, int maxValue) {

        final long maxOffset = Math.abs(maxValue - minValue);

        if (maxOffset == 0) {
            return minValue;
        }

        final int randomOffset = LoadTest.RANDOM_GENERATOR.nextInt(new Long(maxOffset).intValue());

        return minValue + randomOffset;
    }

    private static int getLogarithmicRandomValue(int maxValue) {
        final double max = Math.exp(maxValue);

        final double random = LoadTest.RANDOM_GENERATOR.nextDouble() * max;

        for (int i = 0; i <= maxValue; i++) {
            if (random <= Math.exp(i)) {
                return maxValue - i;
            }
        }
        return -1;
    }

    private static String getRandomPrincipal() {
        return LoadTest.PRINCIPAL_SET[LoadTest.getLogarithmicRandomValue(LoadTest.PRINCIPAL_SET.length - 1)];
    }

    private static String getRandomProject() {
        return LoadTest.PROJECT_SET[LoadTest.getLogarithmicRandomValue(LoadTest.PROJECT_SET.length - 1)];
    }

    private static String getRandomPath() {
        return LoadTest.PATH_SET[LoadTest.getLogarithmicRandomValue(LoadTest.PATH_SET.length - 1)];
    }

    private static void delay() {
        try {
            Thread.sleep(getRandomRange(0, 0));
        } catch (InterruptedException ex) {
            Logger.getLogger(LoadTest.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}
